﻿#region Copyright (C) 2007-2008 Team MediaPortal

/*
    Copyright (C) 2007-2008 Team MediaPortal
    http://www.team-mediaportal.com
 
    This file is part of MediaPortal II

    MediaPortal II is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    MediaPortal II is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with MediaPortal II.  If not, see <http://www.gnu.org/licenses/>.
*/

#endregion

using System;
using System.Threading;
using System.Collections;
using MediaPortal.Core;
using MediaPortal.Core.General;
using MediaPortal.UI.Presentation.Models;
using MediaPortal.UI.Presentation.Workflow;
using LyricsEngine;
using MediaPortal.UI.Presentation.DataObjects;

namespace MyLyrics
{
    /// <summary>
    /// Example for a Viewmodel
    /// the screenfile to this model is located at:
    /// /Skins/default/helloworld.xaml
    /// </summary>
    public class MyLyricsModel : ILyricForm, IWorkflowModel
    {

        #region Const

        public const string MYLYRICS_MODEL_ID_STR = "A2E4C4BB-E8F7-4d9c-AE95-128419F7BEE0";
        public static Guid MYLYRICS_MODEL_ID = new Guid(MYLYRICS_MODEL_ID_STR);

        public const string MYLYRICS_HOME_ID_STR = "A3A4775E-9CD1-4bbb-A67C-EA80F2024D4E";
        public static Guid MYLYRICS_HOME_ID = new Guid(MYLYRICS_HOME_ID_STR);

        public const string MYLYRICS_SELECT_ID_STR = "F4D9CBD4-FF56-4448-B6DB-8106CEC73930";
        public static Guid MYLYRICS_SELECT_ID = new Guid(MYLYRICS_SELECT_ID_STR);

        public const string MYLYRICS_RESULT_ID_STR = "38DCC838-104E-4dd3-9836-A07C6C5F2F9B";
        public static Guid MYLYRICS_RESULT_ID = new Guid(MYLYRICS_RESULT_ID_STR);

                /// <summary>
        /// Another localized string resource.
        /// </summary>
        protected const string COMMAND_TRIGGERED_RESOURCE = "[Lyrics.ButtonTextCommandExecuted]";

        public const string MODEL_ID_STR = "A2E4C4BB-E8F7-4d9c-AE95-128419F7BEE0";
        public static readonly Guid MODEL_ID = new Guid(MODEL_ID_STR);

        #endregion

        #region Private fields

        private string _artist = "Radiohead";
        private string _title = "Karma Police";
        private string _lyric;

        private string[] _sitesToSearch;

        private ILyricsEngine _lyricsEngine;
        private Thread _lyricsEngineWorkerThread;         // worker thread

        private ManualResetEvent _eventStopThread;
        private bool _lyricFound;

        #endregion

        // TODO: Privates to be considered later
        private bool m_LyriccontrollerIsWorking;

        #region Protected fields

        // Mode 1: Select song to search
        protected bool _inSelectSongDialog = false;
        protected ItemsList _selectSongMenu = new ItemsList();

        #endregion

        #region Private fields

        private AbstractProperty _lyricStringProperty;

        #endregion

        /// <summary>
        /// Constructor... this one is called by the ModelManager when access from the screenfiles
        /// to the model is needed (via reflection)
        /// </summary>
        public MyLyricsModel()
        {
            _lyricStringProperty = new WProperty(typeof(string), "My lyric!");
        }

        /// <summary>
        /// some property that can be accessed
        /// </summary>
        public String LyricString
        {
            get
            {
                return (String)LyricProperty.GetValue();
            }
            set
            {
                LyricProperty.SetValue(value);
            }
        }

        /// <summary>
        /// Dependency Property for our string... this is needed
        /// if our string shouldn't be static, so the skinning engine knows
        /// that it should update the display when the string has changed
        /// 
        /// NOTE: when databinding from the XAML to this a property it will always first look for "XYZProperty"
        /// if that one is not found, it will bind to "XYZ"... so in our case if you databind to "HelloString" it will
        /// first try to find a "HelloStringProperty" property to bind to, if that doesn't succeed it will bind to the
        /// "HelloString" String property...
        /// </summary>
        public AbstractProperty LyricProperty
        {
            get { return _lyricStringProperty; }
        }

        public string Artist
        {
            get { return _artist; }
            set { _artist = value; }
        }

        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        public string Lyric
        {
            get { return _lyric; }
            set { _lyric = value; }
        }

        public ItemsList Songs
        {
            get {
                ItemsList itemsList = new ItemsList();
                ListItem listItem = new ListItem("Test1", "Test1Value");
                itemsList.Add(listItem);
                return itemsList;                    
            }
            set { ; }
        }


        /// <summary>
        /// this will change the HelloWorld Property string
        /// </summary>
        public void GoToMyLyricsScreen(Guid guid)
        {
            if (Artist != null && Title != null)
            {
                LyricString = Artist.ToString() + Title.ToString();
            }

            _lyric = "test test test";

            if (guid == MYLYRICS_RESULT_ID)
            {
                //_eventStopThread = new ManualResetEvent(false);
                //_eventStopThread.Reset();

                //_lyricFound = false;

                //_sitesToSearch = SelectSitesToSearch();

                //ServiceRegistration.Set<ILyricsEngine>(new LyricsController());

                //_lyricsEngine = ServiceRegistration.Get<ILyricsEngine>();
                //_lyricsEngine.Initialize(this, _eventStopThread, _sitesToSearch, false, false, null, null);


                //// create worker thread instance
                //ThreadStart job = delegate
                //{
                //    _lyricsEngine.Run();
                //};

                //_lyricsEngineWorkerThread = new Thread(job);
                //_lyricsEngineWorkerThread.Name = "LrcFinder search";
                //_lyricsEngineWorkerThread.Start();

                //_lyricsEngine.AddNewLyricSearch(_artist, _title, _artist /* TODO: MediaPortalUtil.GetStrippedPrefixArtist(m_artist, m_strippedPrefixStrings)*/);

                //m_LyriccontrollerIsWorking = true;

                _lyricStringProperty.SetValue("" + " at " + "");
                _lyric = "dfdsafjasdlfkj";
            }

            //IWorkflowManager workflowManager = ServiceScope.Get<IWorkflowManager>();
            //workflowManager.NavigatePush(guid);
        }

        #region ILyricForm Members

        public object[] UpdateString
        {
            set { throw new NotImplementedException(); }
        }

        public object[] UpdateStatus
        {
            set {  }
        }

        public object[] LyricFound
        {
            set
            {
                //if (m_lyricsFound == false)
                //{
                    string lyricText = (String)value[0];
                    string artist = (String)value[1];
                    string title = (String)value[2];
                    string site = (String)value[3];

                    // If the lrc or lyric found matches the currently playing show the lyric else don't!
                    //if (_artist.Equals(artist) && _title.Equals(title))
                    //{
                    _lyricStringProperty.SetValue(lyricText + " at " + site);
                    _lyric = lyricText;

                    //SaveLyricToDatabase(artist, title, lyricText, site, site.Equals("LrcFinder"));

                    //if (m_CurrentTrackTag != null)
                    //{
                    //    SaveLyricToTagLists(m_CurrentTrackTag.FileName, lyricText);
                    //}
                    //}

                    //m_SearchingState = (int)SEARCH_STATE.NOT_SEARCHING;
                    m_LyriccontrollerIsWorking = false;
                //}

            }
        }

        public object[] LyricNotFound
        {
            set {  }
        }

        public object[] ThreadFinished
        {
            set { }
        }

        public string ThreadException
        {
            set { }
        }

        #endregion


        private string[] SelectSitesToSearch()
        {
            ArrayList sitesToSearch = new ArrayList();

            //if (m_useLrcFinder && Setup.IsMember("LrcFinder"))
            //{
            //    sitesToSearch.Add("LrcFinder");
            //}

            //if (m_useLyricWiki && Setup.IsMember("LyricWiki"))
            //{
            sitesToSearch.Add("LyricWiki");
            //}
            //if (m_useActionext && Setup.IsMember("Actionext"))
            //{
            sitesToSearch.Add("Actionext");
            //}
            //if (m_useActionext && Setup.IsMember("LyrDB"))
            //{
            sitesToSearch.Add("LyrDB");
            //}
            //if (m_useLyrics007 && Setup.IsMember("Lyrics007"))
            //{
            sitesToSearch.Add("Lyrics007");
            //}
            //if (m_useLyricsOnDemand && Setup.IsMember("LyricsOnDemand"))
            //{
            sitesToSearch.Add("LyricsOnDemand");
            //}
            //if (m_useSeekLyrics && Setup.IsMember("SeekLyrics"))
            //{
            sitesToSearch.Add("SeekLyrics");
            //}
            //if (m_useHotLyrics && Setup.IsMember("HotLyrics"))
            //{
            sitesToSearch.Add("HotLyrics");
            //}

            return (string[])sitesToSearch.ToArray(typeof(string));
        }

        // Stop worker thread if it is running.
        // Called when user presses Stop button of form is closed.
        private void StopThread()
        {
            if (_lyricsEngineWorkerThread != null && _lyricsEngineWorkerThread.IsAlive)  // thread is active
            {
                // set event "Stop"
                _eventStopThread.Set();

                _lyricsEngineWorkerThread = null;
                _lyricsEngine = null;
            }

            m_LyriccontrollerIsWorking = false;
        }

        #region IWorkflowModel Members

        public Guid ModelId
        {
            get { return MODEL_ID; }
        }

        public bool CanEnterState(NavigationContext oldContext, NavigationContext newContext)
        {
            //Guid workflowStateId = newContext.WorkflowState.StateId;
            //if (workflowStateId == WF_STATE_ID_LYRICS_MAIN)
            //    return true;
            //if (workflowStateId == WF_STATE_ID_LYRICS_RESULT)
            //    return true;
            //return false;

            return true;
        }

        public void EnterModelContext(NavigationContext oldContext, NavigationContext newContext)
        {
        }

        public void ExitModelContext(NavigationContext oldContext, NavigationContext newContext)
        {
        }

        public void ChangeModelContext(NavigationContext oldContext, NavigationContext newContext, bool push)
        {

        }

        public void Deactivate(NavigationContext oldContext, NavigationContext newContext)
        {

        }

        public void ReActivate(NavigationContext oldContext, NavigationContext newContext)
        {

        }

        public void UpdateMenuActions(NavigationContext context, System.Collections.Generic.IDictionary<Guid, WorkflowAction> actions)
        {
            // Nothing to do here
        }

        public ScreenUpdateMode UpdateScreen(NavigationContext context, ref string screen)
        {
            return ScreenUpdateMode.AutoWorkflowManager;
        }

        #endregion
    }
}
